﻿#include "udpmsg.h"
#include "qdebug.h"

#include <QDataStream>
#include <qiodevice.h>

UdpMsg::UdpMsg() {
    _tag = 0x4853;
    _ver = 0x0001;
}

QByteArray UdpMsg::ToBA()
{
    QByteArray buffer;
    QDataStream out(&buffer, QIODevice::ReadWrite);
    out.setVersion(QDataStream::Qt_6_7);
    out << _tag << _ver << _inc << _cmd << _subCmd << _data;
    quint16 crc = GetCrc16(buffer);
    out << crc;
    return buffer;
}

bool UdpMsg::FromBA(QByteArray ba)
{
    bool retVal = false;
    quint16 crc = 0;

    QDataStream in(&ba,QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_6_7);
    in >> _tag >> _ver >> _inc >> _cmd >> _subCmd >> _data >> crc;

    if(GetSubCmdByMask(4)) {//crc无校验
        retVal = true;
    } else {
        retVal = crc == GetCrc16Value(ba.left(ba.size() - 2));
    }
    return retVal;
}

quint16 UdpMsg::GetCrc16Value(QByteArray pu8Data)
{
    quint8 u8Temp = 0, i = 0;
    quint16 u16Crc = 0, size = 0;
    // pu8Data.append("zr");
    pu8Data.append(0x7A);
    pu8Data.append(0x72);
    size = pu8Data.size();
    while(size--) {
        u8Temp = (u16Crc << 12);
        u16Crc <<= 4;
        u16Crc ^= u16CrcTable[u8Temp^(((quint8)pu8Data[i])>>4)];

        u8Temp = (u16Crc>>12);
        u16Crc <<= 4;
        u16Crc ^= u16CrcTable[u8Temp^(((quint8)pu8Data[i])&0x0f)];
        i++;
    }
    return u16Crc;
}

quint16 UdpMsg::GetCrc16(QByteArray ba)
{
    int crc = 0;
    quint8 u8Temp;
    int i = 0;
    ba.append(0x7A);
    ba.append(0x72);
    int size = ba.size();

    while (size-- != 0) {
        u8Temp = (quint8) (((crc << 12) & 0xFF00));
        crc <<= 4;
        crc ^= u16CrcTable[(u8Temp ^ (ba[i] >> 4)) & 0x0F];

        u8Temp = (quint8) (((crc >> 12)));
        crc <<= 4;
        crc ^= u16CrcTable[(u8Temp ^ (ba[i] & 0x0F)) & 0x0F];
        i++;
    }

    // 确保返回值是16位的
    return crc & 0xFFFF;
}

bool UdpMsg::GetSubCmdByMask(int mask)
{
    return (_subCmd >> mask & 0x01);
}
const quint16 UdpMsg::u16CrcTable[16] = { //CRC余式表
    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef
};
